-- 我自定义的协议
-- struct jtt1078_stream_protocol
-- {
	-- char frameheader[4];
	-- unsigned int v1;
	-- unsigned short v2;
	-- char* data;
-- }
-- 定义自己的协议，name和description，未添加字段
jtt1078_stream_protocol = Proto("jtt1078", "jtt1078-2016 stream")
jtt1078_stream_protocol.fields = {}

-- 第一个参数用于过滤器的字段，第二个是数据显示时的名称，第三个是数据类型
frameheader = ProtoField.uint8("jtt1078_stream.frameheader", "帧头标识", base.HEX) 
v1 = ProtoField.uint8("jtt1078_stream.v1", "rtp_1", base.HEX)
v2 = ProtoField.uint8("jtt1078_stream.v2", "rtp_2", base.HEX)
sn = ProtoField.uint16("jtt1078_stream.sn", "包序号", base.HEX)
sim = ProtoField.string("jtt1078_stream.sim", "SM卡号", base.ASCII)
ch = ProtoField.uint8("jtt1078_stream.ch", "逻辑通道号", base.DEC)
datatype_split = ProtoField.uint8("jtt1078_stream.datatype_split", "数据类型及分包标记", base.HEX)
timestamp = ProtoField.uint64("jtt1078_stream.timestamp", "时间戳", base.HEX)
LIFI = ProtoField.uint16("jtt1078_stream.LIFI", "Last I Frame Interval", base.HEX)
LFI = ProtoField.uint16("jtt1078_stream.LFI", "Last Frame Interval", base.HEX)
data_size = ProtoField.uint16("jtt1078_stream.data_size", "数据长度", base.HEX)
data = ProtoField.none("jtt1078_stream.data", "数据体", base.unicode)
	
-- 声明协议的字段
jtt1078_stream_protocol.fields = {
	frameheader,
	v1,
	v2,
	sn,
	sim,
	ch,
	datatype_split,
	timestamp,
	LIFI,
	LFI,
	data_size,
	data
}

-- buffer：包的数据
-- pinfo: 显示的信息
-- tree：包结构的关系
function jtt1078_stream_protocol.dissector(buffer, pinfo, tree)
	if buffer:len() == 0 then return end
	
	pinfo.cols.protocol = jtt1078_stream_protocol.name --显示在protocol列的名字
	local subtree = tree:add(jtt1078_stream_protocol, buffer(), "jtt1078-2016音视频流及透传数据 Copyright ©2024-2099 大千版权所有") --显示在数据查看
	
	-- 解析成两个分支
	local head_st = subtree:add(jtt1078_stream_protocol, buffer(), "码流数据报文")
	
	-- 根据字段大小，添加到子树
	head_st:add_le(frameheader, buffer(0,4)) --little-endian，从0位置解析4个字节
	head_st:add_le(v1, buffer(4,1))
	head_st:add_le(v2, buffer(5,1))
	
	local sn_tmp = buffer(6,2)
	local sn_str = string.format("%d", sn_tmp:le_uint())
	head_st:add_le(sn, sn_tmp):append_text(" (" .. sn_str .. ")")
	local sim_tmp = buffer(8,6)
	local simstr = sim2string(sim_tmp)
	head_st:add_le(sim, sim_tmp):append_text(" (" .. simstr .. ")")
	head_st:add_le(ch, buffer(14,1))
	head_st:add_le(datatype_split, buffer(15,1))
	head_st:add_le(timestamp, buffer(16,8))
	head_st:add_le(LIFI, buffer(24,2))
	head_st:add_le(LFI, buffer(26,2))
	local dsz = buffer(28,2)
	local sz = string.format("%d", dsz:le_uint())
	head_st:add_le(data_size, dsz):append_text(" (" .. sz .. ")")
	head_st:add_le(data, buffer(30, buffer:len()-30))	
end


-- todo bcd编码转字符串
function sim2string(sim)
	local simstr = "13670193174"
	return simstr
end

local tcp_port = DissectorTable.get("tcp.port") --如果获取tcp就是tcp.port
tcp_port:add(7778, jtt1078_stream_protocol) --抓到的7778端口的数据，按my_proto的规则来解析

local udp_port = DissectorTable.get("udp.port") --如果获取tcp就是tcp.port
udp_port:add(7778, jtt1078_stream_protocol) --抓到的7778端口的数据，按my_proto的规则来解析

